package edu.ucdavis.gwt.gis.client;


import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;

import edu.ucdavis.cstars.client.ESRI;
import edu.ucdavis.cstars.client.InfoWindowBase;
import edu.ucdavis.cstars.client.MapWidget;
import edu.ucdavis.cstars.client.SpatialReference;
import edu.ucdavis.cstars.client.Util;
import edu.ucdavis.cstars.client.control.Position;
import edu.ucdavis.cstars.client.dijits.Scalebar;
import edu.ucdavis.cstars.client.dijits.Scalebar.AttachTo;
import edu.ucdavis.cstars.client.dijits.Scalebar.ScalebarUnit;
import edu.ucdavis.cstars.client.event.MapLoadHandler;
import edu.ucdavis.cstars.client.geometry.Geometry;
import edu.ucdavis.cstars.client.geometry.Point;
import edu.ucdavis.cstars.client.layers.ArcGISTiledMapServiceLayer;
import edu.ucdavis.cstars.client.layers.LOD;
import edu.ucdavis.cstars.client.layers.Layer;

import edu.ucdavis.gwt.gis.client.arcgiscom.ArcGisImportPanel;
import edu.ucdavis.gwt.gis.client.config.BasemapConfig;
import edu.ucdavis.gwt.gis.client.config.GadgetConfig;
import edu.ucdavis.gwt.gis.client.config.LayerConfig;
import edu.ucdavis.gwt.gis.client.draw.DrawControl;
import edu.ucdavis.gwt.gis.client.extras.GwtGisInfoWindow;
import edu.ucdavis.gwt.gis.client.layers.DataLayer;
import edu.ucdavis.gwt.gis.client.layers.FeatureCollectionDataLayer;
import edu.ucdavis.gwt.gis.client.layers.ImageServerDataLayer;
import edu.ucdavis.gwt.gis.client.layers.KmlDataLayer;
import edu.ucdavis.gwt.gis.client.layers.MapServerDataLayer;
import edu.ucdavis.gwt.gis.client.layers.DataLayer.DataLayerLoadHandler;
import edu.ucdavis.gwt.gis.client.layers.DataLayer.DataLayerType;
import edu.ucdavis.gwt.gis.client.layout.LayerMenuCreateHandler;
import edu.ucdavis.gwt.gis.client.layout.LayersPanel;
import edu.ucdavis.gwt.gis.client.layout.RightShadow;
import edu.ucdavis.gwt.gis.client.layout.RootLayout;
import edu.ucdavis.gwt.gis.client.state.ClientStateManager;
import edu.ucdavis.gwt.gis.client.state.CloudLoadHandler;
import edu.ucdavis.gwt.gis.client.toolbar.BasemapGallery;
import edu.ucdavis.gwt.gis.client.toolbar.Toolbar;
import edu.ucdavis.gwt.gis.client.print.PrintPage;
import edu.ucdavis.gwt.gis.client.resources.GadgetResources;

/**
 * Main class.  Create this, then add a loadhandler and customize as you wish (see examples in wiki).
 * 
 * @author Justin Merz
 */
public class GisClient {

	/**
	 * Load handler for when all standard functionality is loaded 
	 */
	public interface GisClientLoadHandler {
		public void onLoad();
	}
	private GisClientLoadHandler loadHandler = null;
	
	// website config file
	private GadgetConfig config = null;
	// main table map sits 
	private RootLayout layout = new RootLayout();
	// main panel the application is attached to
	private SimplePanel rootPanel = null;
	// gwt-esri map object
	protected MapWidget map = null;
	// top toolbar
	protected Toolbar toolbar = null;
	// right hand layers (contains all the legends) panel
	protected LayersPanel layersPanel = new LayersPanel();
	
	// old fashion are we using IE 7/8 flag
	protected static boolean isIE7 = false;
	private static boolean isIE8 = false;
	// last known client width
	private static  int lastWidth = 0;
	// last known client height
	private static int lastHeight = 0;
	
	// default basemap for application
	public static String DEFAULT_BASEMAP = "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer?app=gwtgis";
	// token to be added to all basemap layer ids'
	public static String BASEMAP_TOKEN = "__base_";
	
	// handler for adding application specific menu's to each layer menu (on right hand side)
	public static LayerMenuCreateHandler layerMenuCreateHandler = null;
	
	// curstom info window
	private static InfoWindowBase customInfoWindow = null;
	
	private DataLayer zoomToLayer = null;
	private boolean fullScreen = true;
	private RootPanel gwtAnchor = null;
	
	public GisClient() {}
	
	public GisClient(SimplePanel rootPanel) {
		this.rootPanel = rootPanel;
		fullScreen = false;
	}
	
	
	/**
	 * Set load handler for client.  This fires when the client is ready for developer to customize.
	 * Customizations included adding items to layer menu as well as adding functionality to the
	 * map itself.
	 * 
	 * @param loadHandler - handler to fire when client is ready
	 */
	public void load(GisClientLoadHandler loadHandler) {
		
		DataManager.INSTANCE.setClient(GisClient.this);
		CompatibilityTester.test();
		
		// are we using crappy internet explorer?
		if( Window.Navigator.getUserAgent().contains("MSIE 7.") ) isIE7 = true;
		if( Window.Navigator.getUserAgent().contains("MSIE 8.") ) isIE8 = true;
		if( isIE7 || isIE8 ) { // inject IE css
			addIECss();
		}
		
		config = getConfig();
		DataManager.INSTANCE.setConfig(config);
		
		// did config supply a parent panel?

		if( rootPanel == null ) {
			if( config.getAnchorDiv().length() > 0 ) {
				rootPanel = new SimplePanel();
				gwtAnchor = RootPanel.get(config.getAnchorDiv());
				rootPanel.setSize(gwtAnchor.getOffsetWidth()+"px", gwtAnchor.getOffsetHeight()+"px");
				gwtAnchor.add(rootPanel);
				fullScreen = false;
			} else {
				rootPanel = new SimplePanel();
				RootPanel.get().add(rootPanel);
				fullScreen = true;
				if( isIE7 ) rootPanel.getElement().setAttribute("scroll", "no");
				RootPanel.get().getElement().getStyle().setMargin(0, Unit.PX);
				RootPanel.get().getElement().getStyle().setPadding(0, Unit.PX);
			}
		}
		rootPanel.getElement().getStyle().setOverflow(Overflow.HIDDEN);
		
		String debug = Window.Location.getParameter("debug");
		if( debug != null ) {
			if( debug.contentEquals("true") ) Debugger.INSTANCE.show();
		}
		
		// set the default time in which esri timesout
		ESRI.setTimeout(20000);
		
		this.loadHandler = loadHandler;
		
		// load gadget css
		GadgetResources.INSTANCE.css().ensureInjected();

		// if print mode, jump to that code and quit
		String mode = Window.Location.getParameter("mode");
		if( mode != null ){
			if( mode.contentEquals("print") ){
				PrintPage printPage = DataManager.INSTANCE.getPrintPage();
				if( printPage != null ) {
					printPage.init(rootPanel);
					return;
				}
			}
		}
		
		// let the map event handler setup it's loading screen
		MapEventStatusHandler.INSTANCE.init(this);
		
		// request esri packages and wait for them to load
		Util.addRequiredPackage(Util.Package.ESRI_LAYERS_OSM);
		Util.addRequiredPackage(Util.Package.ESRI_DIJIT_BASEMAPGALLERY);
		Util.addRequiredPackage(Util.Package.ESRI_INFOWINDOWBASE);
		Util.addRequiredPackage(Util.Package.ESRI_DIJIT_SCALEBAR);
		Util.addRequiredPackage(Util.Package.ESRI_LAYERS_KMLLAYER);
		Util.addRequiredPackage(Util.Package.ESRI_TOOLBARS_DRAW);
		Util.addRequiredPackage(Util.Package.ESRI_TOOLBARS_EDIT);
		Util.addRequiredPackage(Util.Package.ESRI_TASKS_PRINTTASK);
		Util.addEsriLoadHandler(onEsriLoad);
	}
	
	// Runs after the esri libraries are loaded
	private Runnable onEsriLoad = new Runnable() {
		@Override
		public void run() {		
			// create the map with a new base layer
			ArcGISTiledMapServiceLayer.Options layerOptions = ArcGISTiledMapServiceLayer.Options.create();
			layerOptions.setId(BASEMAP_TOKEN+"init");
			ArcGISTiledMapServiceLayer layer = ArcGISTiledMapServiceLayer.create(DEFAULT_BASEMAP, layerOptions);
			map = createMap(layer, onMapLoad);
			
			// set the map for the map status handler
			MapEventStatusHandler.INSTANCE.setMap(map);
			DataManager.INSTANCE.setMap(map);
			
			// add the map to the main layout
			layout.setMap(map);
			
			// add the layout to the root panel (whatever that might be)
			rootPanel.add(layout);
		}
	};
	
	// Runs after the map is loaded with a baselayer
	private MapLoadHandler onMapLoad = new MapLoadHandler(){
		@Override
		public void onLoad() {
			
			// Update the status of the loading screen
			MapEventStatusHandler.INSTANCE.setLoadingLayers();
			
			// update the map size to fill the layout
			updateAppSize(true);
			
			// start adding controls to the map
			addControls();		
			
			layout.setLayersPanel(layersPanel);
			
			// make sure the basemap gallery is aware of the map
			BasemapGallery.INSTANCE.setMap(map);
			
			// make sure we are not loading from the 'cloud' 
			if( Window.Location.getParameter("id") == null ) {
				// add layers to map 
				addLayers();
	
				// add additional basemaps
				addBasemaps();
			}

			// case where we have no pre-loaded layers
			onLayersLoaded();
			
			MapEventStatusHandler.INSTANCE.setDone();
		}
	};
	
	/**
	 * Expand all layer panels to show their legends 
	 **/
	public void expandLegends(boolean expand) {
		layersPanel.setExpanded(expand);
	}
	
	/**
	 * Set handler to fire each time a new layer menu is created.
	 * (optional)
	 * 
	 * @param handler
	 */
	public static void setLayerMenuCreateHandler(LayerMenuCreateHandler handler) {
		layerMenuCreateHandler = handler;
	}
	
	/**
	 * Get the handler that should be fired each time a menu is created.
	 * (optional)
	 * 
	 * @return LayerMenuCreateHandler
	 **/
	public static LayerMenuCreateHandler getLayerMenuCreateHandler() {
		return layerMenuCreateHandler;
	}
	
	/**
	 * Fires when the map is almost ready to go
	 **/
	protected void onLayersLoaded() {
		
		// set listeners for window is resized. we will need to resize the map.
		Window.addResizeHandler(new ResizeHandler(){
			@Override
			public void onResize(ResizeEvent event) {
				resizeTimer.cancel();
				resizeTimer.schedule(200);
			}
		});
	
		if( loadHandler != null ) loadHandler.onLoad();
		
		if( Window.Location.getParameter("id") != null ) {
			
			Timer t = new Timer() {
				public void run() {
					String id = Window.Location.getParameter("id");
					ClientStateManager.clearClientState();
					ClientStateManager.loadClientStateFromCloud(id, new CloudLoadHandler(){
						@Override
						public void onLoadComplete() {}
					});
				}
			};
			t.schedule(500);
			
		} else if( Window.Location.getParameter("map") != null ) {
			
			centerMap();
			Timer t = new Timer() {
				public void run() {
					String map = Window.Location.getParameter("map");
					ClientStateManager.loadClientStateFromJson("", map);
				}
			};
			t.schedule(1000);
		
		} else if ( Window.Location.getParameter("arcmap") != null ) {
			
			centerMap();
			Timer t = new Timer() {
				public void run() {
					String id = Window.Location.getParameter("arcmap");
					ArcGisImportPanel.loadArcGisMap(id);
				}
			};
			t.schedule(1000);
			
			
		} else {
			
			centerMap();
			
			if( zoomToLayer != null ) {
				new Timer() {
					 public void run() {
						zoomToLayer.addLoadHandler(new DataLayerLoadHandler(){
							@Override
							public void onDataLoaded(final DataLayer dataLayer) {
								if( dataLayer.getType() == DataLayerType.MapServer ) {
									((MapServerDataLayer) dataLayer).zoomToLayerExtent();
								} else if( dataLayer.getType() == DataLayerType.KML ) {
									((KmlDataLayer) dataLayer).zoomToLayerExtent();
								}
							}
						});
						
					 }
				 }.schedule(500);
			} else {
				// double check
				new Timer() {
					 public void run() {
						 centerMap();
					 }
				 }.schedule(500);
			}
		}
	}
	
	/**
	 * Center the map for the first time
	 **/
	private void centerMap() {
		if( config.hasCenterPoint() ){
			Point centerPoint = Point.create(
						(float) config.getCenterx(), 
						(float) config.getCentery(), 
						SpatialReference.create(4269)
			);
			centerPoint = (Point) Geometry.geographicToWebMercator(centerPoint);
			try {
				map.centerAndZoom(centerPoint, config.getZoomLevel());
			} catch (Exception e) {
				Debugger.INSTANCE.catchException(e, "GisClient", "centerMap()");
			}
		}
	}
	
	/**
	 * Add custom basemaps to client
	 **/
	private void addBasemaps() {
		JsArray<BasemapConfig> bmaps = config.getAdditionalBasemaps();
		for( int i = 0; i < bmaps.length(); i++ ) {
			BasemapConfig bc = bmaps.get(i);
			toolbar.getBasemapSelector().add(bc.getName(), bc.getUrl(), bc.getIconUrl());
		}
	}
	
	/**
	 * Add website config layers to the client.  This also adds any layers passed in the ?url=
	 * parameter
	 **/
	private int addLayers() {
		int hcount = 0;
		JsArray<LayerConfig> dls = config.getDataLayers();
		for( int i = dls.length()-1; i >=0; i-- ) {
			String url = dls.get(i).getUrl();
			DataLayer dl = null;
			
			if( url.endsWith("kml") || url.endsWith("kmz") ) {
				dl = new KmlDataLayer(dls.get(i));
			} else if ( url.contains("MapServer") ) {
				dl = new MapServerDataLayer(dls.get(i));
			}
			
			if( dl != null ) {
				DataManager.INSTANCE.addDataLayer(dl);
				//dl.addLoadHandler(layerLoadHandler);
				layersPanel.add(dl);
				hcount++;
			}
		}
		
		// check for url parameter
		try {
			String url = Window.Location.getParameter("url");
			if( url != null ){
				if( !url.matches("^(http|https|ftp)://.*") ) url  = "http://"+url;
				
				String title = url.replaceAll("/MapServer.*", "").replaceAll(".*/", "").replaceAll("\\.kml", "").replaceAll("\\.kmz", "");
				DataLayer dl = addLayer(url, title, 80);
				
				if( dl != null ) {
					
					String zoom = Window.Location.getParameter("zoom");
					if( zoom != null ) {
						if( zoom.contentEquals("true") ) {
							zoomToLayer = dl;
						}
					}
					
					String show = Window.Location.getParameter("show");
					if( show != null ) {
						if( show.contentEquals("true") ) dl.setShowLegendOnLoad(true);
					}
					
					hcount++;
				}
			}
		} catch (Exception e) {
			Debugger.INSTANCE.catchException(e, "GisClient", "addLayers()");
		}
		
		return hcount;
	}

	/**
	 * Add a datalayer to the client
	 * 
	 * @param dl - layer to add
	 * @return DataLayer
	 */
	public DataLayer addLayer(DataLayer dl) {	
		try {
			if( dl != null ) {
				DataManager.INSTANCE.addDataLayer(dl);
				
				if( dl.getType() == DataLayerType.FeatureCollection ) {
					FeatureCollectionDataLayer fcl = (FeatureCollectionDataLayer) dl;
					DrawControl.INSTANCE.addLayer(fcl);
					fcl.addToMap(map);
				} else { 
					layersPanel.add(dl);
				}
			}
		} catch (Exception e) {
			Debugger.INSTANCE.catchException(e, "GisClient", "addLayer(DataLayer)");
		}
		return dl;
	}
	
	/**
	 * Add a new layer to the client
	 * 
	 * @param url - url of layer
	 * @param title - name of layer (for menu)
	 * @param opacity - default opacity
	 * @return DataLayer
	 */
	public DataLayer addLayer(String url, String title, int opacity) {
		DataLayer dl = null;
		
		try {
			if( url.endsWith("kml") || url.endsWith("kmz") ) {
				dl = new KmlDataLayer(url, title, opacity);
			} else if ( url.contains("MapServer") ) {
				dl = new MapServerDataLayer(url, title, opacity);
			} else if ( url.contains("ImageServer") ) {
				dl = new ImageServerDataLayer(url, title, opacity);
			}
			
			if( dl != null ) {
				dl.setShowLegendOnLoad(true);
				DataManager.INSTANCE.addDataLayer(dl);
				layersPanel.add(dl);
			}
		} catch (Exception e) {
			Debugger.INSTANCE.catchException(e, "GisClient", "addLayer(url, title, opacity)");
		}
		
		return dl;
	}
	
	/**
	 * Remove a layer from the client
	 * 
	 * @param dl - layer to be removed
	 */
	public void removeLayer(DataLayer dl) {
		dl.removeFromMap(map);
		DataManager.INSTANCE.removeDataLayer(dl);
		MapEventStatusHandler.INSTANCE.removeLayer(dl.getId());
		layersPanel.remove(dl);
	}
	
	/**
	 * Add controls to the map
	 */
	protected void addControls() {
		// Main toolbar
		toolbar = new Toolbar();
		toolbar.setPosition(0, 0, Position.TOP_LEFT);
		map.addControl(toolbar);
		
		// decor
		if( !GisClient.isIE7 ) {
			map.addControl(new RightShadow());
		}
		
		// scale bar
		Scalebar.Parameters params = Scalebar.Parameters.create();
		params.setAttachTo(AttachTo.BOTTOM_RIGHT);
		params.setScalebarUnit(ScalebarUnit.ENGLISH);
		params.setMap(map);
		new Scalebar(params);
		
		// add map event status control to the map
		MapEventStatusHandler.INSTANCE.addControl();
	}
	
	public int getWidth() {
		if( fullScreen ) {
			return Window.getClientWidth();
		} else if ( gwtAnchor != null ) {
			return gwtAnchor.getOffsetWidth();
		}
		return rootPanel.getOffsetWidth();
	}
	
	public int getHeight() {
		if( fullScreen ) {
			return Window.getClientHeight();
		} else if ( gwtAnchor != null ) {
			return gwtAnchor.getOffsetHeight();
		}
		return rootPanel.getOffsetHeight();
	}
	
	public int getLeft() {
		if( fullScreen ) return 0;
		return rootPanel.getAbsoluteLeft();
	}
	
	public int getTop() {
		if( fullScreen ) return 0;
		return rootPanel.getAbsoluteTop();
	}
	
	public SimplePanel getRootPanel() {
		return rootPanel;
	}
	
	/**
	 * Update the application size
	 * 
	 * @param force - by default if current width & height are equal to lastWidth
	 * and lastHeight nothing is done.  The force flag pushes on anyway.
	 */
	public void updateAppSize(boolean force) {
		int width = getWidth() - 251;
		int height = getHeight();
		
		if( GisClient.isIE7 || GisClient.isIE8 ) {
			width -= 2;
			height -= 2;
		}
		
		// only update if we need to
		if( force || lastWidth != width || lastHeight != height ){
			map.setSize(width+"px", height+"px");
			
			if( layersPanel != null ){
				if( GisClient.isIE7 ) {
					layersPanel.setHeight(height-1);
				} else {
					layersPanel.setHeight(height);
				}
			}
			//rootPanel.setSize(Window.getClientWidth()+"px", height+"px");
			
			lastWidth = width;
			lastHeight = height;
		}
		
		// resize panel as well
		if ( gwtAnchor != null ) {
			rootPanel.setSize(getWidth()+"px", height+"px");
		}
		
		// double check
		resizeTimer.schedule(250);
	}
	
	/**
	 * A timer for double checking the app is at the correct size.  This is important when scroll bars
	 * popup up and then disappear.  Scheduling a second resize event makes sure the application fills
	 * the entire screen at all times.
	 */
	private Timer resizeTimer = new Timer() {
		@Override
		public void run() {
			updateAppSize(false);
		}
	};

	/**
	 * Get the toolbar control.
	 * 
	 * @return Toolbare
	 */
	public Toolbar getToolbar() {
		return toolbar;
	}
	
	/**
	 * Get the gwt-esri map object.
	 * 
	 * @return MapWidget
	 */
	public MapWidget getMapWidget() {
		return map;
	}
	
	public LayersPanel getLayersPanel() {
		return layersPanel;
	}

	/**
	 * Set a print page for this application
	 * 
	 * @param printPage - print page to use
	 */
	public void setPrintPage(PrintPage printPage) {
		DataManager.INSTANCE.setPrintPage(printPage);
	}
	
	/**
	 * Check the website for a config variable
	 * 
	 * @return GadgetConfig
	 */
	private final native GadgetConfig getConfig() /*-{
		if( typeof mapConfig != 'undefined' ) {
			return mapConfig;
		} else if ( $wnd.mapConfig ) {
			return $wnd.mapConfig;
		}
		return null;
	}-*/;
	
	/**
	 * Static, crap, IE flag.  enough said.
	 * 
	 * @return
	 */
	public static boolean isIE7() {
		return isIE7;
	}
	
	public static boolean isIE8() {
		return isIE8;
	}
	
	/**
	 * Set a custom info window to be used.  See the ESRI docs for more information on custom info windows.
	 * 
	 * @param customWindow
	 */
	public static void setCustomInfoWindow(InfoWindowBase customWindow) {
		customInfoWindow = customWindow;
	}
	
	/**
	 * Create a new map.
	 * 
	 * @param initLayer - layer map is to initialize to
	 * @param handler - load handler
	 * @return MapWidget
	 */
	public static MapWidget createMap(Layer initLayer, MapLoadHandler handler) {
		return createMap(initLayer, handler, null);
	}
	
	public static MapWidget createMap(Layer initLayer, MapLoadHandler handler, LOD[] lods) {
		// not using bottom two resolutions, so we have to specify all resolutions that we want
		// esri basemap resolutions defined here: http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer
		if( lods == null ) {
			lods = new LOD[] {
				LOD.create(0,156543.033928, 591657527.591555),
				LOD.create(1, 78271.5169639999, 295828763.795777),
				LOD.create(2, 39135.7584820001, 147914381.897889),
				LOD.create(3, 19567.8792409999, 73957190.948944),
				LOD.create(4, 9783.93962049996, 36978595.474472),
				LOD.create(5, 4891.96981024998, 18489297.737236),
				LOD.create(6, 2445.98490512499, 9244648.868618),
				LOD.create(7, 1222.99245256249, 4622324.434309),
				LOD.create(8, 611.49622628138, 2311162.217155),
				LOD.create(9, 305.748113140558, 1155581.108577),
				LOD.create(10, 152.874056570411, 577790.554289),
				LOD.create(11, 76.4370282850732, 288895.277144),
				LOD.create(12, 38.2185141425366, 144447.638572),
				LOD.create(13, 19.1092570712683, 72223.819286),
				LOD.create(14, 9.55462853563415, 36111.909643),
				LOD.create(15, 4.77731426794937, 18055.954822),
				LOD.create(16, 2.38865713397468, 9027.977411),
				LOD.create(17, 1.19432856685505, 4513.988705),
				LOD.create(18, 0.597164283559817, 2256.994353),
				LOD.create(19, 0.298582141647617, 1128.497176)
			};
		}
		
		MapWidget.Options options = MapWidget.Options.create();
		options.setLods(lods);	

		if( isIE7 || isIE8 ) {
			options.setDisplayGraphicsOnPan(false);
		} else {
			options.setFadeOnZoom(true);
		}
		
		if( customInfoWindow != null ) options.setInfoWindow(customInfoWindow);
		else options.setInfoWindow(new GwtGisInfoWindow());
		
		MapWidget map = new MapWidget(initLayer, handler, options);
		return map; 
	}
	
	private void addIECss() {
		Element style = DOM.createElement("link");
		style.setAttribute("rel", "stylesheet");
		style.setAttribute("href", GWT.getModuleBaseURL()+"/IE.css");
		Document.get().getElementsByTagName("head").getItem(0).appendChild(style);
		if( isIE7 ) {
			style = DOM.createElement("link");
			style.setAttribute("rel", "stylesheet");
			style.setAttribute("href", GWT.getModuleBaseURL()+"/IE7.css");
			Document.get().getElementsByTagName("head").getItem(0).appendChild(style);
		}
	}
	
	public class RPanel extends SimplePanel {
	    public RPanel(String id) {
	      super(DOM.getElementById(id));
	    }
	  }
	
	
	
}
